package com.mars.push.core.channel.firm.handler;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.mars.push.api.common.MessageInput;
import com.mars.push.core.channel.AbstractPushChannel;
import com.mars.push.core.channel.PushMessage;
import com.mars.push.core.channel.firm.config.HuaConfig;
import com.mars.push.core.channel.firm.dto.FirmPushMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URLEncoder;
import java.text.MessageFormat;

/**
 * @Author King
 * @create 2020/5/25 11:15
 */
@Slf4j
@Component
public class HuaPushChannel extends AbstractPushChannel {

    /**
     * 获取认证Token的URL
     */
    private static final String tokenUrl = "https://login.vmall.com/oauth2/token";
    /**
     * 应用级消息下发API
     */
    private static final String apiUrl = "https://api.push.hicloud.com/pushsend.do";
    /**
     * 下发通知消息的认证Token
     */
    private String accessToken;
    /**
     * accessToken的过期时间
     */
    private long tokenExpiredTime;

    @Autowired
    private HuaConfig config;


    @Override
    protected Object androidPush0(PushMessage pushMessage) {
        FirmPushMessage m = (FirmPushMessage) pushMessage;
        if (tokenExpiredTime <= System.currentTimeMillis()) {
            try {
                refreshToken();
            } catch (IOException e) {
                log.info(e.getMessage(), e);
            }
        }
        //目标设备Token
        JSONArray deviceTokens = new JSONArray();
        deviceTokens.add(m.getDeviceToken());

        JSONObject msg = new JSONObject();
        //3: 通知栏消息，异步透传消息请根据接口文档设置
        msg.put("type", 1);
        String token = m.getDeviceToken();
        m.setDeviceToken(null);
        //通知栏消息body内容
        msg.put("body", new Gson().toJson(m));

        //华为PUSH消息总结构体
        JSONObject hps = new JSONObject();
        hps.put("msg", msg);

        JSONObject payload = new JSONObject();
        payload.put("hps", hps);

        log.info("send push to HMS {}", payload);

        try {
            String postBody = MessageFormat.format(
                    "access_token={0}&nsp_svc={1}&nsp_ts={2}&device_token_list={3}&payload={4}",
                    URLEncoder.encode(accessToken, "UTF-8"),
                    URLEncoder.encode("openpush.message.api.send", "UTF-8"),
                    URLEncoder.encode(String.valueOf(System.currentTimeMillis() / 1000), "UTF-8"),
                    URLEncoder.encode(deviceTokens.toString(), "UTF-8"),
                    URLEncoder.encode(payload.toString(), "UTF-8"));

            String postUrl = apiUrl + "?nsp_ctx=" + URLEncoder.encode("{\"ver\":\"1\", \"appId\":\"" + config.getAppId() + "\"}", "UTF-8");
            String response = httpPost(postUrl, postBody, 5000, 5000);
            log.info("Push to {} response {}", token, response);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            log.error("Push to {} with exception", token, e);
        }
        return "ok";
    }

    @Override
    public PushMessage createMessage(MessageInput input) {
        FirmPushMessage message = new FirmPushMessage();
        BeanUtils.copyProperties(input, message);
        return message;
    }

    @Override
    protected void onSuccess(PushMessage message, Object result) {

    }

    @Override
    protected void onFail(PushMessage message, Object result) {

    }

    @Override
    protected void onException(PushMessage message, Object result) {

    }

    @Override
    protected Object allPush0(PushMessage pushMessage) {
        return null;
    }

    @Override
    protected Object iosPush0(PushMessage pushMessage) {
        return null;
    }


    private void refreshToken() throws IOException {
        log.info("hms refresh token");
        String msgBody = MessageFormat.format(
                "grant_type=client_credentials&client_secret={0}&client_id={1}",
                URLEncoder.encode(config.getAppSecret(), "UTF-8"), config.getAppId());
        String response = httpPost(tokenUrl, msgBody, 5000, 5000);
        JSONObject obj = JSONObject.parseObject(response);
        accessToken = obj.getString("access_token");
        tokenExpiredTime = System.currentTimeMillis() + obj.getLong("expires_in") - 5 * 60 * 1000;
        log.info("hms refresh token with result {}", response);
    }


    public String httpPost(String httpUrl, String data, int connectTimeout, int readTimeout) throws IOException {
//        OutputStream outPut = null;
//        HttpURLConnection urlConnection = null;
//        InputStream in = null;
//
//        try {
//            URL url = new URL(httpUrl);
//            urlConnection = (HttpURLConnection) url.openConnection();
//            urlConnection.setRequestMethod("POST");
//            urlConnection.setDoOutput(true);
//            urlConnection.setDoInput(true);
//            urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
//            urlConnection.setConnectTimeout(connectTimeout);
//            urlConnection.setReadTimeout(readTimeout);
//            urlConnection.connect();
//
//            // POST data
//            outPut = urlConnection.getOutputStream();
//            outPut.write(data.getBytes("UTF-8"));
//            outPut.flush();
//
//            // read response
//            if (urlConnection.getResponseCode() < 400) {
//                in = urlConnection.getInputStream();
//            } else {
//                in = urlConnection.getErrorStream();
//            }
//
//            List<String> lines = IOUtils.readLines(in, urlConnection.getContentEncoding());
//            StringBuffer strBuf = new StringBuffer();
//            for (String line : lines) {
//                strBuf.append(line);
//            }
//            log.info(strBuf.toString());
//            return strBuf.toString();
//        } finally {
//            IOUtils.closeQuietly(outPut);
//            IOUtils.closeQuietly(in);
//            if (urlConnection != null) {
//                urlConnection.disconnect();
//            }
//        }
        return null;
    }
}
